import os.path

import pandas as pd
from sklearn.model_selection import KFold, train_test_split
from typing import Union
from module.logic_module.file_manager.model import FileManagerModel


class MLEngine:
    """机器学习模型的训练核，整合了机器学习研究的一般方法"""
    def __init__(self):
        self.ori_feature: pd.DataFrame = None
        self.ori_target: pd.DataFrame = None
        self.X_train: pd.DataFrame = None
        self.X_test: pd.DataFrame = None
        self.y_train: pd.Series = None
        self.y_test: pd.Series = None
        # 归一化参数字典既存储缩放参数又存储了模型相应的因子名
        self.scale_param: dict = {}  # key为字段名，value为列表，列表包含归一化方案对应的关键数据
        self.final_model = None  # 训练好的机器学习模型
        pass

    def ori_data(self, data, feature_col_ls: list[str], target_col: str):
        self.ori_feature = data[feature_col_ls]
        self.ori_target = data[target_col]

        pass

    def scale_data(self, scale_plan="mean_std"):
        # 生成归一化feature

        # 生成归一化target

        # 生成归一化参数信息

        pass

    def set_div_data(self, plan):
        if plan == '1':
            self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(self.scale_feature, self.scale_target, test_size=0.2, shuffle=False)
        else:
            raise ValueError("意外的分割类型。")

    def train_model(self):
        # 训练模型模块，由子类重写，将模型返回


        pass

    def save_model(self):
        # # 保存模型到结果文件夹
        # # 用file_manager保存model到结果文件夹指定位置
        # FileManagerModel.save_model()
        #
        # # 保存归一化参数到结果文件夹
        # # 用file_manager保存json到结果文件夹指定位置
        #
        # FileManagerModel.save_json()
        # # 保存模型性能特征数据到结果文件夹
        # # 用file_manager保存json到结果文件夹指定位置
        #
        # FileManagerModel.save_json()
        #

        pass

    def restore_data(self, data: Union[pd.Series, pd.DataFrame], plan="mean_std"):
        if self.scale_param:
            pass
        else:
            raise ValueError("归一化参数为空，逻辑错误。")
        if plan == "mean_std":
            # 根据归一化参数，将归一化数据按字段还原
            if isinstance(data, pd.Series):
                # 数据属于Series类

                pass
            elif isinstance(data, pd.DataFrame):
                # 数据属于DataFrame类

                pass
        else:
            pass
        data2 = ""
        return data2

    def load_model(self, folder_name):
        # 传入模型相关数据对应文件夹，自动读取模型和归一化参数
        model_path = os.path.join(folder_name, ".model")
        scale_param_path = os.path.join(folder_name, ".json")
        self.final_model = FileManagerModel.load_model(model_path)
        self.scale_param = FileManagerModel.read_json(scale_param_path)
        pass

    def predict(self, feature_dc: dict):
        # 传入特征字典，输出预测值
        pre_scale_target = self.final_model.predict(feature_dc)
        # 还原

        pass










